package com.joy.openggl.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;

/**
 * 
 * @author agui
 */
public class ClassUtil {

	/**
	 * 获取对象的属性
	 */
	public static Object getProperty(Object owner, String fieldName) throws Exception {
		Class<?> ownerClass = owner.getClass();
		Field field = ownerClass.getDeclaredField(fieldName);
		field.setAccessible(true);
		Object property = field.get(owner);
		return property;
	}

	/**
	 * 赋值给对象的私有属性
	 */
	public static void setProperty(Object owner, String fieldName, Object value)
			throws Exception {
		Class<?> ownerClass = owner.getClass();
		Field field = ownerClass.getDeclaredField(fieldName);
		field.setAccessible(true);
		field.set(owner, value);
	}

	/**
	 * 获取类的静态属性
	 */
	public static Object getStaticProperty(Class<?> clz, String fieldName) throws Exception {
		Field field = clz.getField(fieldName);
		Object property = field.get(clz);
		return property;
	}

	/**
	 * 执行对象的方法
	 */
	public static Object invokeMethod(Object owner, String methodName, Object[] args)
			throws Exception {
		Class<?> ownerClass = owner.getClass();
		Class<?>[] argsClass = new Class[args.length];
		for (int i = 0, j = args.length; i < j; i++) {
			argsClass[i] = args[i].getClass();
		}
		Method method = ownerClass.getMethod(methodName, argsClass);
		return method.invoke(owner, args);
	}

	/**
	 * 执行类的静态方法
	 */
	public static Object invokeStaticMethod(String className, String methodName, Object[] args)
			throws Exception {
		Class<?> ownerClass = Class.forName(className);
		Class<?>[] argsClass = new Class[args.length];
		for (int i = 0, j = args.length; i < j; i++) {
			argsClass[i] = args[i].getClass();
		}
		Method method = ownerClass.getMethod(methodName, argsClass);
		return method.invoke(null, args);
	}

	/**
	 * 新建实例
	 */
	public static Object newInstance(String className, Object[] args) throws Exception {
		Class<?> newoneClass = Class.forName(className);
		Class<?>[] argsClass = new Class[args.length];
		for (int i = 0, j = args.length; i < j; i++) {
			argsClass[i] = args[i].getClass();
		}
		Constructor<?> cons = newoneClass.getConstructor(argsClass);
		return cons.newInstance(args);
	}
	
	public static void clean(final ByteBuffer byteBuffer) {
	    if (byteBuffer.isDirect()) {
		    try {
		        Object cleaner = invoke(byteBuffer, "cleaner");
		        invoke(cleaner, "clean");
		    }catch (Exception e) { 
		       e.printStackTrace();
		    }
	    }
	}

	private static Object invoke(final Object target, String methodName) throws Exception {
		final Method method = target.getClass().getMethod(methodName);
		return AccessController.doPrivileged(new PrivilegedAction<Object>() {
			public Object run() {
				try {
					method.setAccessible(true);
					return method.invoke(target);
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		});
	}

}
